"""
参数
以下是调用函数时可使用的正式参数类型：
必需参数 : 必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样
关键字参数: 使用关键字参数允许函数调用时参数的顺序与声明时不一致,函数调用使用关键字参数（参数名字）来确定传入的参数值
默认参数：调用函数时，如果没有传递参数，则会使用默认参数
不定长参数：你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数 参考fun5~fun8写法

返回值：
return 变量
只有 return 则返回空
"""


# 函数示例
def fun1():
    print("无参数函数")


def fun2(a, b):
    print("接受2个参数，并计算他们的和 并返回")
    return a + b


# 调用此函数，若不传参，则使用默认值a=1.b=2
def fun3(a=1, b=2):
    sum = a + b
    print("接受2个参数，并含有默认值并计算他们的和 ", a, "+", b, "=", sum)
    return sum


# 返回多个值,返回一个元组
def fun33(a=1, b=2):
    sum = a + b
    a1 = a - b
    print(f'返回多个值 a+b={sum} a-b={a1}')
    return sum, a1


# 给参数初始化一个数值来表明是何种类型，这里是列表
def fun4(list1=[]):
    list1.append("a")
    print("接受一个列表参数，并追加了一个元素")


# 加了星号 * 的参数会以元组(tuple)的形式导入，存放所有未命名的变量参数。
def fun5(*list2):
    # 将元组list2转化为列表
    list1 = list(list2)
    print("将不定长参数初始化为列表，list1 = ", list1)


def fun6(a, *list2, c):
    list1 = list(list2)
    list1.append(a)
    list1.append(c)
    print(f' 将不定长参数初始化为列表， a={a}, list1 ={list1} c={c}')


# 接受一个字典参数
def fun7(**map1):
    print("接受一个字典参数 ，map1 = ", map1)


# 接受一个字典参数,map1后无法再添加参数，否则语法错误，因为格式问题，第三个参数需要指定名字，则写法与**map 的传参重叠，则系统无法识别
def fun8(a, **map1):
    print("接受一个字典参数 ，map1 = ", map1)


"""
匿名函数
Python 使用 lambda 来创建匿名函数。
所谓匿名，意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式，函数体比 def 简单很多。
lambda 的主体是一个表达式，而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间，且不能访问自己参数列表之外或全局命名空间里的参数。
虽然 lambda 函数看起来只能写一行，却不等同于 C 或 C++ 的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率

格式：lambda [arg1 [,arg2,.....argn]]:expression
"""


def lmd():
    sum1 = lambda a, b: a + b
    # 利用lmd表达函数快速计算2个数的和 ，只能在lmd作用域里面使用
    print(f'1+3={sum1(1, 3)}')


if __name__ == '__main__':
    fun1()
    fun2(2, 3)
    # 3种方式
    fun3()
    fun3(3, 9)
    fun3(b=11, a=10)  # 打乱顺序传参

    c1, c2 = fun33(5, 2)
    print("两个变量接受两个返回值 : ", c1, c2)
    c3 = fun33(5, 2)
    print(f'一个变量接受多个返回值 类型为元组 {c3[0]}, {c3[1]}')

    temp_list = [1, 2, 3]
    fun4(temp_list)

    fun5(1, 2, 3, 4)
    fun6(1, 2, 3, c=4)

    fun7(a=2, b=3)
    fun8(2, a=2, c=3, b=3)
